package jdk8.lambda.why;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Desc:   总目标需求，找出符合条件的学生
 * @author: cww
 * @DateTime: 2020-06-06 20:59
 */

public class Main {

    /**
     * 需求 1 找出哪些来自中国的学生
     */
    public static void findStudent(List<Student> students) {
        List<Student> list = new ArrayList<>();

        for (Student student : students) {
            if ("china".equals(student.getAge())){
                list.add(student);
            }
        }
    }

    /**
     * 需求1 实现的进阶，将地区参数化
     * @param students
     */
    public static void findStudentByArea(List<Student> students,String area) {
        List<Student> list = new ArrayList<>();

        for (Student student : students) {
            if (area.equals(student.getAge())){
                list.add(student);
            }
        }
    }

    /**
     * 需求 2 找出 年龄 > 20 岁的学生
     * @param students
     * @param age
     */
    public static void findStudentByAge(List<Student> students,int age) {
        List<Student> list = new ArrayList<>();

        for (Student student : students) {
            if (student.getAge() > age){
                list.add(student);
            }
        }
    }

    /**
     * 需求 3 满足随时能改变查询 地区和年龄 的学生列表，用状态标识，案例就不写了
     */

    /**
     * 改进方式1 用策略模式
     * 将过滤条件抽象为一个接口，不同的过滤方式有不同的接口实现 如 StudentAgePredicate / StudentAreaPredicate
     * 这样代码比较优美，如果有别的需求只要实现接口即可，但是每个需求都要写相关的接口实现
     */

    public static void findStudent(List<Student> list, StudentPredicate p){
        List<Student> students = new ArrayList<>();
        for (Student student : list) {
            if (p.filter(student)){
                students.add(student);
            }
        }
        List<Student> finalStudents = students;
        list.forEach((Student s) -> {p.filter(s);
            finalStudents.add(s);});
        students = students.stream().filter(s -> "china".equals(s.getArea())).collect(Collectors.toList());
    }

    /**
     * 策略改进
     * 使用匿名类方式
     * 匿名内部类经编译后会生成对应的class文件，格式为XXX$n.class
     */

    public static void findStudentByAnoy() {
        List<Student> sourceStu = new ArrayList<>();
        findStudent(sourceStu, new StudentPredicate() {
            @Override
            public boolean filter(Student student) {
                return "china".equals(student);
            }
        });
    }

    /**
     * 进阶 使用 lambda
     * 而lambda代码经过编译后生成一个private方法，方法名格式为lambda$maindemo$n
     */

    public static void findStudentByLam() {
        List<Student> sourceStu = new ArrayList<>();
        findStudent(sourceStu, (Student pam) -> "china".equals(pam.getArea()));
    }
}















